package com.ahua.mallchat.common.service.impl;

import com.ahua.mallchat.common.common.event.ItemReceiveEvent;
import com.ahua.mallchat.common.dao.UserBackpackDao;
import com.ahua.mallchat.common.domain.enums.system.YesOrNoEnum;
import com.ahua.mallchat.common.domain.enums.user.IdempotentEnum;
import com.ahua.mallchat.common.domain.pojo.UserBackpack;
import com.ahua.mallchat.common.service.IUserBackpackService;
import com.ahua.mallchat.common.service.common.LockService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * <p>
 * 用户背包表 服务类
 * </p>
 *
 * @author <a href="https://github.com/zongzibinbin">abin</a>
 * @since 2023-03-19
 */
@Service
public class UserBackpackServiceImpl implements IUserBackpackService {

    @Resource
    private LockService lockService;

    @Resource
    private UserBackpackDao userBackpackDao;
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String relationId) {
        //先获取幂等号
        String idempotent = getIdempotent(itemId, idempotentEnum, relationId);
        //通过分布式锁来实现
        //todo 弄一个分布式锁注解
        lockService.executeWithLock("acquireItem" + idempotent, () -> {
            UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
            if (Objects.nonNull(userBackpack)) {
                //不为空说明 已经存过 直接返回就行
                return;
            }
            //发放物品
            UserBackpack backpack = UserBackpack
                    .builder()
                    .uid(uid)
                    .itemId(itemId)
                    .status(YesOrNoEnum.NO.getStatus())
                    .idempotent(idempotent)
                    .build();
            userBackpackDao.save(backpack);
            applicationEventPublisher.publishEvent(new ItemReceiveEvent(this, backpack));
        });
    }

    /**
     * 获取幂等号
     */
    private String getIdempotent(Long itemId, IdempotentEnum idempotentEnum, String relationId) {
        return String.format("%d_%d_%s", itemId, idempotentEnum.getType(), relationId);
    }

}
